// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Closure.js 1`] = `
/***
 * Test tracking of variable types across closure calls.
 * @flow
 */

function takes_string(_:string) { }

// global write from function
//

var global_x = "hello";

function global_f() { }
function global_g() { global_x = 42; }

global_f();
takes_string(global_x); // ok

global_g();
takes_string(global_x); // error

global_x = 42;  // shouldn't pollute linear refinement

// local write from function
//

function local_func() {

  var local_x = "hello";

  function local_f() { }
  function local_g() { local_x = 42; }

  local_f();
  takes_string(local_x); // ok

  local_g();
  takes_string(local_x); // error

  local_x = 42;  // shouldn't pollute linear refinement
}

// global write from method
//

var global_y = "hello";

var global_o = {
  f: function() { },
  g: function() { global_y = 42; }
}

global_o.f();
takes_string(global_y); // ok

global_o.g();
takes_string(global_y); // error

global_y = 42;  // shouldn't pollute linear refinement

// local write from method
//

function local_meth() {

  var local_y = "hello";

  var local_o = {
    f: function() { },
    g: function() { local_y = 42; }
  }

  local_o.f();
  takes_string(local_y); // ok

  local_o.g();
  takes_string(local_y); // error

  local_y = 42;  // shouldn't pollute linear refinement
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/***
 * Test tracking of variable types across closure calls.
 * @flow
 */

function takes_string(_: string) {}

// global write from function
//

var global_x = "hello";

function global_f() {}
function global_g() {
  global_x = 42;
}

global_f();
takes_string(global_x); // ok

global_g();
takes_string(global_x); // error

global_x = 42; // shouldn't pollute linear refinement

// local write from function
//

function local_func() {
  var local_x = "hello";

  function local_f() {}
  function local_g() {
    local_x = 42;
  }

  local_f();
  takes_string(local_x); // ok

  local_g();
  takes_string(local_x); // error

  local_x = 42; // shouldn't pollute linear refinement
}

// global write from method
//

var global_y = "hello";

var global_o = {
  f: function() {},
  g: function() {
    global_y = 42;
  }
};

global_o.f();
takes_string(global_y); // ok

global_o.g();
takes_string(global_y); // error

global_y = 42; // shouldn't pollute linear refinement

// local write from method
//

function local_meth() {
  var local_y = "hello";

  var local_o = {
    f: function() {},
    g: function() {
      local_y = 42;
    }
  };

  local_o.f();
  takes_string(local_y); // ok

  local_o.g();
  takes_string(local_y); // error

  local_y = 42; // shouldn't pollute linear refinement
}

`;

exports[`cond_havoc.js 1`] = `
// @flow

// from sam, https://github.com/facebook/flow/issues/780
// call to f() within if should properly havoc x.
//
function example(b: bool): number {
  var x = 0;
  function f() { x = "" }
  if (b) {
    f();
  }
  return x; // error, string ~/~> number (return type anno) TODO
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow

// from sam, https://github.com/facebook/flow/issues/780
// call to f() within if should properly havoc x.
//
function example(b: boolean): number {
  var x = 0;
  function f() {
    x = "";
  }
  if (b) {
    f();
  }
  return x; // error, string ~/~> number (return type anno) TODO
}

`;

exports[`const.js 1`] = `
/***
 * consts retain refinements
 * @flow
 */

// global, anybody can call it at any time
var call_me: () => void = () => {};

function g(x: ?number) {

  const const_x = x;
  if (const_x) {
    // ok: if const_x is truthy here, it's truthy everywhere
    call_me = () => { var y:number = const_x; };
  }

  var var_x = x;
  if (var_x) {
    // error: var_x might no longer be truthy when call_me is called
    call_me = () => { var y:number = var_x; };  // error
  }
  var_x = null;
}

function h(x: number | string | boolean) {

  const const_x = x;
  if (typeof(const_x) == "number") {
    call_me = () => { var y:number = const_x; };  // ok
  } else if (typeof(const_x) == "string") {
    call_me = () => { var y:string = const_x; };  // ok
  } else if (typeof(const_x) == "boolean") {
    call_me = () => { var y:boolean = const_x; };  // ok
  }

  var var_x = x;
  if (typeof(var_x) == "number") {
    call_me = () => { var y:number = var_x; };  // error
  } else if (typeof(var_x) == "string") {
    call_me = () => { var y:string = var_x; };  // error
  } else if (typeof(var_x) == "boolean") {
    call_me = () => { var y:boolean = var_x; };  // error
  }
}

// in a galaxy far far away
call_me();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/***
 * consts retain refinements
 * @flow
 */

// global, anybody can call it at any time
var call_me: () => void = () => {};

function g(x: ?number) {
  const const_x = x;
  if (const_x) {
    // ok: if const_x is truthy here, it's truthy everywhere
    call_me = () => {
      var y: number = const_x;
    };
  }

  var var_x = x;
  if (var_x) {
    // error: var_x might no longer be truthy when call_me is called
    call_me = () => {
      var y: number = var_x;
    }; // error
  }
  var_x = null;
}

function h(x: number | string | boolean) {
  const const_x = x;
  if (typeof const_x == "number") {
    call_me = () => {
      var y: number = const_x;
    }; // ok
  } else if (typeof const_x == "string") {
    call_me = () => {
      var y: string = const_x;
    }; // ok
  } else if (typeof const_x == "boolean") {
    call_me = () => {
      var y: boolean = const_x;
    }; // ok
  }

  var var_x = x;
  if (typeof var_x == "number") {
    call_me = () => {
      var y: number = var_x;
    }; // error
  } else if (typeof var_x == "string") {
    call_me = () => {
      var y: string = var_x;
    }; // error
  } else if (typeof var_x == "boolean") {
    call_me = () => {
      var y: boolean = var_x;
    }; // error
  }
}

// in a galaxy far far away
call_me();

`;
